<template>
	<div class="c-previewSimple">
        <slot></slot>
        <div class="contentwp">
            <div v-if="chartType === 'sankey' && dataObject.nodeList" 
                class="chartwp" ref="_chart" 
                :style="{ minHeight: sankeyHeight + 'px' }"></div>
            <div v-if="chartType === 'simple'" 
                class="chartwp" ref="_simpleMap"></div>
        </div>
	</div>
</template>

<script>
import config from './config'
import * as dhx from 'public/3thComponents/diagram/codebase/diagramWithEditor.js'
import 'public/3thComponents/diagram/codebase/diagramWithEditor.css'
import echarts from 'echarts'
import { myRequest } from 'public/service/api/myRequest'

export default {
	name: 'previewSimple',
	// components: { VChart },
	data() {
		return {
			theme: '',
			option: {},
			editor: null, //diagram的编辑器
			diagram: null, //diagram实例
			title: '',
			modelType: 'entity',
			type: 'entity',
			className: 'sys_energySimple',
			dataObject: {},
			sourceObj: {}, // 查询数据源接口后，获得的data
			sankeyHeight: 0,
			myChart: null,
		}
	},
	methods: {
		async init(rowId, data) {
			if (rowId) {
				let classObject = this.$modelObject.create(this.modelType)
				let res = await classObject.queryById(rowId)

				if (res) {
					this.dataObject = classObject.record.values.config
					this.title = classObject.record.values.sf_sname
				}
			} else {
				this.dataObject = data
			}
		},
		// 用来支持二次过滤: condition: { beginTime: '2024-03-21', endTime: '2024-03-30' }
		async queryData(condition) {
			// 1. 查询source数据
			// 2. 根据配置的公式，计算出每个节点的value
			// 3. 转换成能流图需要的格式，然后渲染：能流图或者单线图
			await this.getSourceData(condition)
			this.calcValue()
			if (this.chartType === 'sankey') {
				if (!this.sankeyHeight) {
                    this.sankeyHeight = this.dataObject.sankeyHeight || 800
				}
                this.$nextTick(() => {
                    this.myChart = echarts.init(this.$refs._chart, 'light')
                    this.initSankey(this.dataObject)
                })
			} else if (this.chartType === 'simple') {
				this.initSimple(this.dataObject)
			}
		},
		// 获取数据源
		async getSourceData(condition) {
			let allRequest = []
			let sourceList = this.dataObject.sourceList
			let nodeList = this.dataObject.nodeList
			let queryParam = {
				ids: [],
				...(condition || {}),
			}

			if (nodeList && nodeList.length) {
				nodeList.forEach((item, index) => {
					item.calcType === 'source' && item.sourceValue 
						&& queryParam.ids.push(item.sourceValue)
					nodeList[index].value = 0
				})
			}
			if (sourceList && sourceList.length && queryParam.ids.length) {
				sourceList.forEach(item => {
					item.name && item.path && allRequest.push(
						myRequest(
							{
								url: item.path,
								method: 'post',
							},
							queryParam
						)
					)
				})

				let resList = await Promise.all(allRequest)
				resList.forEach((res, index) => {
					// res = condition
					// 	? { 19827: 127, 19828: 128, 19829: 129, 19830: 130, 19831: 131 }
					// 	: { 19827: 27, 19828: 28, 19829: 29, 19830: 30, 19831: 31 }
					this.sourceObj[sourceList[index].name] = res
				})
			} else {
				this.sourceObj.s1 = {}
			}
		},
		// 计算每个节点的value
		calcValue() {
			let nodeList = this.dataObject.nodeList
			let obj = this.sourceObj.s1 || this.sourceObj.source1 || {}

			// 1. 计算叶子节点的value
			nodeList
				.filter(item => 
                    (item.calcType === 'source' && item.sourceValue) ||
                    (item.calcType === 'input' && item.inputValue)
                )
				.forEach(item => {
					if (item.calcType === 'source') {
						item.value = obj[item.sourceValue]
					} else if (item.calcType === 'input') {
						item.value = item.inputValue
					}
				})
			// 2. 根据叶子节点的value，汇总到父节点
			let parentItem = nodeList.find(item => (item.nodeId = 'root'))
			let rootValue = 0

			this.calcParentValue(parentItem, nodeList)
			nodeList
				.filter(item => item.prev.includes('root'))
				.forEach(item => {
					rootValue += item.value
				})
			parentItem.value = rootValue
			// console.log("file: previewSimple.vue calcValue2", nodeList, rootValue)
		},
		calcParentValue(parentItem, nodeList) {
			let child = nodeList.filter(item => 
                item.prev.includes(parentItem.nodeId)
            )

			if (child.length) {
				let sum = 0
				child.forEach(item => {
					let res = this.calcParentValue(item, nodeList)
					sum += res
					// console.log('🚀 ~ calcParentValue ~ res:', item.title, res, sum)
				})
				if (parentItem.value) {
					return parentItem.value
				} else {
					parentItem.value = sum
					return sum
				}
			} else {
				return parentItem.value || 0
			}
		},
		//#region 初始化能流图
		initSankey(dataObject) {
			let source = dataObject.web
			let data = []
			let links = []
			let conf = {}

			dataObject.nodeList.forEach(item => {
				conf[item.nodeId] = item
			})

			source.forEach(item => {
				let nodeItem = conf[item.id] || {}

				if (item.type === 'line') {
					let value = conf[item.to] ? conf[item.to].value : 0

					links.push({
						source: item.from,
						target: item.to,
						value: value || 1,
					})
				} else {
					data.push({
						name: item.id,
						title: nodeItem.title,
					})
				}
			})
			this.option = config.sankeyOption({
				// title: this.title,
				data,
				links,
			})
			console.log('file: previewSimple.vue:184  initSankey', dataObject, { data, links })
			this.myChart.setOption(this.option)
		},
		//#endregion

		//#region 初始化 单线图
		initSimple(dataObject) {
			if (!this.diagram) {
				this.diagram = new dhx.Diagram(
					this.$refs._simpleMap,
					// { type: 'default', width: '100%', }
					this._getOptions()
				)
				this._init_template()
			}
			this.diagram.data.parse(dataObject.web)
		},
		_getOptions() {
			return {
				shapeBarWidth: 320,
				scalePreview: 0.8,
				type: 'default', //"default" | "org" | "mindmap"模式中的一种（缺省|组织结构|脑图）
				select: false, //鼠标框选是否有效
				lineConfig: {
					lineType: 'line', //"dash" | "line"，虚线|实线
				},
				gridStep: 10, //网格间距
				/**以下default模式有效*/
				autoplacement: {
					//图元连接方式配置
					mode: 'edges', //"direct" | "edges"，edges为在图元边连接点处连接
					graphPadding: 100, //图元间距，缺省为200
				},
				lineGap: 50, //连接线与图元的间距
				/**以上default模式有效*/
				/***********以下配置编辑器*******************************************/
				/**配置 toolbar 的命令按钮是否可以显示*/
				controls: {
					apply: false,
					reset: false,
					export: false,
					import: false,
					autoLayout: false,
					historyManager: false,
					editManager: false,
					scale: true,
					gridStep: false,
				},
			}
		},
		_init_template() {
			/**附加图元模板*/
			let additionalTemplate = this._getAdditionalTemplate()
			Object.keys(additionalTemplate).map(key => {
				this.diagram.addShape(key, {
					template: additionalTemplate[key].template,
					defaults: additionalTemplate[key].defaults,
				})
			})
		},
		_getAdditionalTemplate() {
			let template = shape => {
				let obj = this.dataObject.nodeList.find(item => 
					item.nodeId === shape.id
				) || {}
				let varName = obj.varName || ''
				let nodeBorderColor = obj.nodeBorderColor || this.dataObject.nodeBorderColor
				let nodeColor = obj.nodeColor || this.dataObject.nodeColor
				let nodeIcon = obj.nodeIcon || this.dataObject.nodeIcon

				return `
                    <div style="border-color: ${nodeBorderColor};color: ${nodeColor}"
                        class="shape-item">
                        <p class="title flex-middle">
                            <span>${obj.title || ''}${varName && obj.title ? ':' : ''}</span>
                            <span class="flex1" style="text-align: center;">${varName}</span>
                        </p>
                        <div class="content flex-middle">
                            <i class="ivu-icon ${nodeIcon}"></i>
                            <span class="value">${obj.value || ''}</span>
                        </div>
                    </div>
                `
			}
			let defaults = { shapeType: 'workCenter' } // width: 90, height: 90,
			return {
				routingRoot: { defaults, template },
				workCenter: { defaults, template },
			}
		},
		//#endregion
	},
	props: {
		chartType: {
			type: String,
			default() {
				return 'sankey' // sankey 能流图, simple 单线图
			},
		},
	},
}
</script>

<style lang="less">
@import './parts/diagram_item.less';

.c-previewSimple {
	// width: 100%;
	// height: calc(~'100vh - 140px');
    // overflow-y: auto;
	padding: 16px 0;
    // display: flex;
    // flex-direction: column;
    .contentwp {
    	height: calc(~'100vh - 200px');
    	overflow-y: auto;
		overflow-x: hidden;
    }
	.chartwp {
		// width: 100%;
		height: 100%;
	}
	.dhx_diagram {
		width: 100%;
		height: 100%;
		background-color: #fff;
	}
}
</style>
